/**
 * @file Medicamento.java
 * @brief Entidad que representa los tipos de medicamentos que existen en farmacia.
 *
 * Copyright (C)  - April [2011]
 *
 * @author Miguel Ángel Díaz López
 * @version 01.00
 * 
 * @footnote e-mail:  admin    at etsiit.es
 */

package GestorFarmacia;

import Definiciones.Definiciones;
import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;
import java.util.Date;
import java.util.ArrayList;

/**
 * @class Medicamento
 * @brief Representa los tipos de medicamentos que existen en farmacia.
 */
public class Medicamento {
    /* Declaración de las variables de instancia */
    private Integer _id_medicamento;          // Identificador único del medicamento
    private Definiciones.ATC _categoria;      // Categoría del medicamento (ATC)
    private String _nombre;                   // Nombre del medicamento
    private String _DCI;                      // Marca del medicamento
    private Definiciones.ViaAdministracion _via_administracion; // Vía de administrar el med.
    private Integer _dosis_unidad;            // Nº de dosis que contiene cada envase
    private Integer _umbral_existencias;      // Cantidad mínima recomendable de "stock"
    private Integer _cantidad_tipica;         // "Stock" típico
    private Definiciones.Estado _estado;      // Estado actual del medicamento en el sistema

    /* Constructor */
    public Medicamento() {
        this._id_medicamento = null;
        this._categoria = null;
        this._nombre = null;
        this._DCI = null;
        this._via_administracion = null;
        this._dosis_unidad = null;
        this._umbral_existencias = null;
        this._cantidad_tipica = null;
        this._estado = null;
    }
    public Medicamento(Integer id_medicamento, Definiciones.ATC categoria, String nombre, String DCIoMarca,
                       Definiciones.ViaAdministracion via, Integer dosis_unidad, Integer umbral, Integer cant_tipica,
                       Definiciones.Estado estado) {
        this._id_medicamento = id_medicamento;
        this._categoria = categoria;
        this._nombre = nombre;
        this._DCI = DCIoMarca;
        this._via_administracion = via;
        this._dosis_unidad = dosis_unidad;
        this._umbral_existencias = umbral;
        this._cantidad_tipica = cant_tipica;
        this._estado = estado;
    }
    
    /* Métodos de clase */
    public static void add ( Medicamento m ) throws SQLException, IOException, ClassNotFoundException {
        MedicamentoDAO.add(m);
    }
    public static void delete ( Medicamento m ) throws SQLException, IOException, ClassNotFoundException {
        MedicamentoDAO.delete(m);
    }
    public static void update ( Medicamento m ) throws SQLException, IOException, ClassNotFoundException {
        MedicamentoDAO.update(m);
    }
    public static Medicamento get ( Integer id_medicamento ) throws SQLException, IOException, ClassNotFoundException {
        Medicamento medicamento_buscado = MedicamentoDAO.get(id_medicamento);
        return medicamento_buscado;
    }
    public static Medicamento[] get ( Definiciones.ATC cat, String nombre, String DCI, Definiciones.ViaAdministracion via,
                             Integer dosis, Integer umbral, Integer cantidad_tipica, Definiciones.Estado estado) throws SQLException, IOException, ClassNotFoundException {
        Medicamento[] l_medicamentos = MedicamentoDAO.get(cat,nombre,DCI,via,dosis,umbral,cantidad_tipica,estado);
        return l_medicamentos;
    }
    public static Medicamento[] getBajasExistencias() throws SQLException, IOException, ClassNotFoundException, ParseException {
        Medicamento[] v_medicamentos = null;
        ArrayList<Medicamento> l_medicamentos = new ArrayList<Medicamento>();
        // Generamos la consulta a la BD con los Medicamentos cuya CANTIDAD en los LOTES se encuentra por debajo del UMBRAL
        Lote[] lotes = LoteDAO.get (null,null,null,null,null,Definiciones.Estado.DISPONIBLE);
        if(lotes == null) return v_medicamentos;
        for(int i=0; i<lotes.length; i++){
            Medicamento m_i = lotes[i].getMedicamento();
            if(m_i.getEstadoMedicamento().toString().equals("DISPONIBLE")){
                int umbral = m_i.getUmbralExistenciasMedicamento();
                int restantes = 0;
                for(int j=0; j<lotes.length; j++)// Calculamos unidades restantes de dicho medicamento por LOTES
                    if(m_i.getIdMedicamento() == lotes[j].getMedicamento().getIdMedicamento())
                        restantes += lotes[j].getUnidadesRestantesLote();
                if ( restantes < umbral )
                    l_medicamentos.add(m_i);
            }
        }
        // Devolvemos vector de medicamentos con bajas existencias
        if(l_medicamentos.size()>0){
            v_medicamentos = new Medicamento[l_medicamentos.size()];
            l_medicamentos.toArray(v_medicamentos);
        }
        return v_medicamentos;
    }
    
    /* Métodos de instancia */
    /**
     * @brief Consultas sobre el objeto "Medicamento"
     * @return "consulta"
     */
    public Integer getIdMedicamento() {
        return this._id_medicamento;
    }
    public Definiciones.ATC getCategoriaMedicamento() {
        return this._categoria;
    }
    public String getDCI() {
        return this._DCI;
    }
    public Integer getDosisPorUnidad() {
        return this._dosis_unidad;
    }
    public Definiciones.ViaAdministracion getViaAdministracion() {
        return this._via_administracion;
    }
    public String getNombreMedicamento() {
        return this._nombre;
    }
    public Integer getUmbralExistenciasMedicamento() {
        return this._umbral_existencias;
    }
    public Integer getCantidadTipicaMedicamento() {
        return this._cantidad_tipica;
    }
    public Definiciones.Estado getEstadoMedicamento() {
        return this._estado;
    }

   /**
     * @brief Modificaciones realizadas en el objeto "Medicamento"
     * @param nuevo valor para dicha modificación
     */
    public void setIdMedicamento(Integer id) {
        this._id_medicamento = id;
    }
    public void setCategoriaMedicamento(Definiciones.ATC cat) {
        this._categoria = cat;
    }
    public void setDCI(String DCI_Marca) {
        this._DCI = DCI_Marca;
    }
    public void setDosisPorUnidad(Integer dosis) {
        this._dosis_unidad = dosis;
    }
    public void setViaAdministracion(Definiciones.ViaAdministracion via) {
        this._via_administracion = via;
    }
    public void setNombreMedicamento(String nombre) {
        this._nombre = nombre;
    }
    public void setUmbralExistenciasMedicamento(Integer umbral) {
        this._umbral_existencias = umbral;
    }
    public void setCantidadTipicaMedicamento(Integer tipica) {
        this._cantidad_tipica = tipica;
    }
    public void setEstadoMedicamento(Definiciones.Estado estado) {
        this._estado = estado;
    }

   /**
     * @brief Buscamos lotes que contengan al medicamentos bajo ciertas circunstancias.
     * @param nada-fecha_caducidad
     */
    public Lote[] getLotesMedicamento() throws SQLException, IOException, ClassNotFoundException, ParseException {
        return LoteDAO.get(this._id_medicamento, null, null, null, null, null);
    }
    
    public Lote[] getLotesMedicamentoCaducados(Date fecha) throws SQLException, IOException, ClassNotFoundException, ParseException {
        Lote[] lotes = null;
        Lote[] v_lotes = null;
        ArrayList<Lote> l_lotes = new ArrayList<Lote>();
        // Buscamos en los LOTES caducados
        lotes = Lote.getLotesCaducados(fecha);
        if(lotes == null) return v_lotes;
        for(int i=0; i<lotes.length; i++){
            if(lotes[i].getIdMedicamento() == this._id_medicamento)
                l_lotes.add(lotes[i]);
        }
        // Devolvemos los lotes caducados*/
        if(l_lotes.size()>0){
            v_lotes = new Lote[l_lotes.size()];
            l_lotes.toArray(v_lotes);
        }
        return v_lotes;
    }
}
